/*
 * Copyright 2010 Assert Developments
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package be.ad.coffeebreak.web;

import be.ad.coffeebreak.web.exceptions.NotFoundException;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.factory.Factory;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * A servlet that dispatches the requests to commands.
 *
 * @author Stefan Bangels
 */
public class DispatchServlet extends HttpServlet {

    @Inject
    protected Factory<Command> commandFactory;

    /**
     * Set the command factory.
     *
     * @param commandFactory the command factory
     */
    @SuppressWarnings("unused")
    void setCommandFactory(Factory<Command> commandFactory) {
        this.commandFactory = commandFactory;
    }

    /**
     * Initializes the servlet.
     *
     * @param servletConfig the servlet configuration
     * @throws ServletException when something terrible has happened
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        ServletContext context = servletConfig.getServletContext();
        Injector injector = (Injector) context.getAttribute(WebConstants.ATTRIBUTE_INJECTOR);
        injector.injectMembers(this);
    }

    /**
     * Processes the request.
     *
     * @param request  the request
     * @param response the response
     * @throws ServletException when something terrible has happened
     * @throws IOException      when something terrible has happened
     */
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // Get the command name
        String commandName = RequestTools.getRelativeURI(request);

        // Create the command
        Command command = commandFactory.create(commandName);
        if (command == null) {
            throw new NotFoundException("command not found: " + commandName);
        }

        // Execute the command
        CommandContext context = new HttpServletCommandContext(request);
        String view = command.execute(context);

        // Dispatch the view
        RequestDispatcher dispatcher = request.getRequestDispatcher(view);
        dispatcher.forward(request, response);
    }

    /**
     * Destroys the servlet.
     */
    @Override
    public void destroy() {
    }

}
